package emediashared.model;

import java.io.File;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;

import emediashared.SharedActivator;
import emediashared.ui.PreferencesDialog;
import emediashared.ui.RemoteNode;

public class SharedRmiClient implements ISharedClient {

	private IRemoteMessageTransfer remoteMessageTransfer;
	private String serverAddress;
	private String serverPort;
	private String rmiName;
	private boolean connected;
	private ArrayList<RemoteNode> children;
	public static final String PORT_SEPARATOR = ":";
	
	public SharedRmiClient(String url, String userName) {
		resetConfiguration(url, userName, null);
	}

	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#resetConfiguration(java.lang.String, java.lang.String)
	 */
	@Override
	public void resetConfiguration(String url, String userName, String repos) {
		String[] split = url.split(PORT_SEPARATOR);
		this.serverAddress = split[0];
		this.serverPort = split[1];
		this.rmiName = userName;
	}
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#connect()
	 */
	@Override
	public boolean connect() {
		if (!connected) {
			try {
				Registry registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue());
				remoteMessageTransfer = (IRemoteMessageTransfer) (registry.lookup(rmiName));
				connected = true;
			} catch (Exception e) {
				SharedActivator.showAndLogError(e);
			}
		}
		return connected;
	}
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#reConnect()
	 */
	@Override
	public void reConnect() {
		connected = false;
		connect();
		children = null;
	}
	
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#getFiles(java.lang.String)
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<IRemoteFile> getFiles(String parent) throws RemoteException {
		return (List<IRemoteFile>) remoteMessageTransfer.execute(ClientRequest.GET_FILES_LIST, null, parent);
	}
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#downloadFile(java.lang.String, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public boolean downloadFile(String sourceFile, String target, IProgressMonitor monitor) throws Exception {
		String remoteLocation = PreferencesDialog.getRemotePath();
		String userName = PreferencesDialog.getUserName();
		File remoteTempDir = new File(remoteLocation, userName);
		remoteTempDir.mkdirs();
		File tempFile = (File) remoteMessageTransfer.execute(ClientRequest.DOWNLOAD_FILE, getWrapperMonitor(monitor),
				sourceFile, remoteTempDir.getAbsolutePath());
		if (tempFile.exists()) {
			try {
				RemoteFile.copy(tempFile.getAbsolutePath(), target, getWrapperMonitor(monitor));
				return true;
			} finally {
				tempFile.delete();
			}
		}
		return false;
	}

	private IRemoteProgressMonitor getWrapperMonitor(final IProgressMonitor monitor) throws RemoteException {
		return new RemoteProgressMonitor() {
			private static final long serialVersionUID = 1L;

			@Override
			public void worked(int work) throws RemoteException {
				monitor.worked(work);
			}

			@Override
			public void done() throws RemoteException {
				monitor.done();
			}

			@Override
			public void beginTask(String name, int totalWork) throws RemoteException {
				monitor.beginTask(name, totalWork);
			}
		};
	}
	
	public static void main(String[] args) {
		String serverAddress= "183.83.26.151"; 
		String serverPort= "3232";
		try {
			new SharedRmiClient(serverAddress + PORT_SEPARATOR + serverPort, "Prasad").printFiles();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public void printFiles() throws RemoteException {
		String root = "C:/EMediaPlayerPlugin/remote";
		List<IRemoteFile> files = (List<IRemoteFile>) remoteMessageTransfer.execute(ClientRequest.GET_FILES_LIST, null,
				root);
		boolean copied = false;
		for (IRemoteFile remoteFile : files) {
			System.out.println(remoteFile.getFilePath() + ":" + remoteFile.isDirectory());
			if (remoteFile.isDirectory()) {
				List<IRemoteFile> nestedFiles = (List<IRemoteFile>) remoteMessageTransfer.execute(ClientRequest.GET_FILES_LIST, null,
						remoteFile.getFilePath());
				for (IRemoteFile nestedRemoteFile : nestedFiles) {
					System.out.println("->->->" + nestedRemoteFile.getFilePath() + ":" + nestedRemoteFile.isDirectory());
					
					if (!nestedRemoteFile.isDirectory() && !copied && nestedRemoteFile.getFilePath().endsWith(".mp3")) {
						File file = (File) remoteMessageTransfer.execute(ClientRequest.DOWNLOAD_FILE, null, nestedRemoteFile.getFilePath(), root);
						remoteMessageTransfer.execute(ClientRequest.DELETE_FILE, null, file.getAbsolutePath());
						copied = true;
					}
				}
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#isConnected()
	 */
	@Override
	public boolean isConnected() {
		return connected;
	}
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#getRmiName()
	 */
	@Override
	public String getName() {
		return rmiName;
	}
	
	
	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#getChildren()
	 */
	@Override
	public List<RemoteNode> getChildren() {
		if (children == null) {
			children = new ArrayList<RemoteNode>();
			try {
				List<IRemoteFile> files = getFiles(null);
				for (IRemoteFile remoteFile : files) {
					children.add(new RemoteNode(remoteFile, null));
				}
			} catch (RemoteException e) {
				children = null;
				SharedActivator.showAndLogError(e);
			}
		}
		return children;
	}

	/* (non-Javadoc)
	 * @see emediashared.model.ISharedClient#isLoaded()
	 */
	@Override
	public boolean isLoaded() {
		return children != null;
	}
}
